<?php
namespace App\Http\Controllers\Admin\Report\Service;

use App\Http\Controllers\Admin\Business\Repository\ComboOrder;
use App\Http\Controllers\Admin\Member\Repository\Member;
use App\Http\Controllers\Admin\Finance\Repository\Account;
use App\Http\Controllers\Admin\Scene\Repository\SceneBuy;
use Illuminate\Support\Facades\Auth;

/**
 * Created by PhpStorm.
 * User: wanghaibo
 * Date: 17/12/8
 * Time: 15:50
 */
class Report
{
    /*
     * 数据库模型
     * 1.销售统计 combo_orders
     * 2.分销统计 account_logs表
     * 3.景点统计 scenic_buy表
     * 默认销售统计
     */
    private $repository;
    private $type;
    private $request;
    private $options;

    public function __construct ($type = 2)
    {
        $this->type = $type;
        switch ($type){
            case 1:
                $this->repository = new ComboOrder();
                break;
            case 2:
                $this->repository = new Account();
                break;
            case 3:
                $this->repository = new SceneBuy();
                break;
            default:
                $this->repository = new Account();
                break;
        }
        $this->type = $type;
    }

    public function getReport($request,$options=[]){
        if($options){
            $this->options = $options;
        }
        $this->request = $request;
        $model = $this->repository;
        $data = [];
        switch ($this->type){
            case 1:
                $return = $this->saleReport($model,$data);
                break;
            case 2:
                $return = $this->accountReport($model,$data);

                break;
            case 3:
                return $this->scenceReport($model,$data);
                break;
            default:
                $return = $this->saleReport($model,$data);
                break;
        }
        return $return;
    }
    private function saleReport($model,$data){
        $title = '销售统计';
        $field = 'price';
        $this->sumReport($model,$title,$data,$field);
        return ['title'=>$title,'data'=>$data];
    }

    private function accountReport($model,$data){
        $title = '分销统计';
        $where = [['type','=',2]];
        $where1 = [['pid','<>',0]];
        $data1 = [];
        $model1 = new Member();
        if(isset($this->request->searchTime)&&$this->request->searchTime!=''){
            $timeArray=explode('~',$this->request->searchTime);
            $start_time=trim($timeArray[0]);
            $end_time=trim($timeArray[1]);
            $start_obj = new \DateTime($start_time);
            $end_obj = new \DateTime($end_time);
            $diff = date_diff($start_obj,$end_obj);
            if(Auth::user()->can('comboAllOrder')){
                $datas = $model->select('created_at','price')->whereBetween('created_at',[$start_time,$end_time])->withTrashed()->where($where)->get();
            }else{
                $datas = $model->select('created_at','price')->whereBetween('created_at',[$start_time,$end_time])->where($where)->get();

            }
            $datasMember = $model1->select('created_at')->whereBetween('created_at',[$start_time,$end_time])->where($where1)->get();
            $test = [];
            //判断相差日子
            if($this->getRange($diff)){
                //大于1年则按年统计
                $title = '年'.$title;
                if($this->isCeil($diff))$diff->y = $diff->y+1;
                for($i = 0;$i<=$diff->y;$i++){
                    $incrementTime = new \DateInterval("P{$i}Y");
                    $date = new \DateTime($start_time);
                    $start_d = date_add($date,$incrementTime);

                    $data[$i] = ['date'=>date_format($start_d,'Y'),'price'=>0];
                    $data1[$i] = ['date'=>date_format($start_d,'Y'),'count'=>0];

                    foreach ($datas as $k=>$v){
                        $temp_date_obj = new \DateTime($v->created_at);
                        if($temp_date_obj->format('Y')==$start_d->format('Y')){
                            $data[$i]['price'] += $v->price;

                        }
                    }
                    foreach ($datasMember as $k=>$v){
                        $temp_date_obj = new \DateTime($v->created_at);
                        if($temp_date_obj->format('Y')==$start_d->format('Y')){
                            $data1[$i]['count']++;
                        }
                    }
                    $data[$i]['price'] = round($data[$i]['price'],2);
                }

            }else{
                //小于或等于一年
                if($this->getRange($diff,'m')){
                    $title = '月'.$title;
                    //大于一个月则按月统计
                    if($diff->y==1&&$diff->m==0)$diff->m=12;
                    if($this->isCeil($diff,'m'))$diff->m = $diff->m+1;

                    for($i = 0;$i<=$diff->m;$i++){
                        $incrementTime = new \DateInterval("P{$i}M");
                        $date = new \DateTime($start_time);
                        $start_d = date_add($date,$incrementTime);
                        //得出结果
                        $data[$i] = ['date'=>date_format($start_d,'Y/m'),'price'=>0];
                        $data1[$i] = ['date'=>date_format($start_d,'Y/m'),'count'=>0];
                        foreach ($datas as $k=>$v){
                            $temp_date_obj = new \DateTime($v->created_at);
                            if($temp_date_obj->format('Y/m')==$start_d->format('Y/m')){
                                $data[$i]['price'] += $v->price;

                            }
                        }
                        foreach ($datasMember as $k=>$v){
                            $temp_date_obj = new \DateTime($v->created_at);
                            if($temp_date_obj->format('Y/m')==$start_d->format('Y/m')){
                                $data1[$i]['count']++;
                            }
                        }
                        $data[$i]['price'] = round($data[$i]['price'],2);

                    }
                }else{
                    //小于或等于一个月
                    if($this->getRange($diff,'d')){
                        $title = '日'.$title;
                        //小于一个月大于一日则天统计
                        if($diff->m==1&&$diff->d==0){
                            $days = date('t',strtotime($start_time));
                            $diff->d = $days;
                        }
                        if($this->isCeil($diff,'d')){
                            $diff->d = $diff->d+1;
                        }
                        for($i = 0;$i<=$diff->d;$i++){
                            $incrementTime = new \DateInterval("P{$i}D");
                            $date = new \DateTime($start_time);
                            $start_d = date_add($date,$incrementTime);
                            $data[$i] = ['date'=>date_format($start_d,'m/d'),'price'=>0];
                            $data1[$i] = ['date'=>date_format($start_d,'m/d'),'count'=>0];
                            foreach ($datas as $k=>$v){
                                $temp_date_obj = new \DateTime($v->created_at);
                                if($temp_date_obj->format('m/d')==$start_d->format('m/d')){
                                    $data[$i]['price'] += $v->price;

                                }
                            }
                            foreach ($datasMember as $k=>$v){
                                $temp_date_obj = new \DateTime($v->created_at);
                                if($temp_date_obj->format('m/d')==$start_d->format('m/d')){
                                    $data1[$i]['count']++;
                                }
                            }
                            $data[$i]['price'] = round($data[$i]['price'],2);


                        }
                    }else{
                        $title = '时'.$title;
                        //小时统计
                        //小于一个月大于一日则天统计
                        if($diff->d==1&&$diff->h==0)$diff->h=24;
                        if($this->isCeil($diff))$diff->h = $diff->h+1;
                        for($i = 0;$i<=$diff->h;$i++){
                            $incrementTime = new \DateInterval("PT{$i}H");
                            $date = new \DateTime($start_time);
                            $start_d = date_add($date,$incrementTime);
                            $data[$i] = ['date'=>date_format($start_d,'H:00'),'price'=>0];
                            $data1[$i] = ['date'=>date_format($start_d,'H:00'),'count'=>0];
                            foreach ($datas as $k=>$v){
                                $temp_date_obj = new \DateTime($v->created_at);
                                if($temp_date_obj->format('d-H')==$start_d->format('d-H')){
                                            $data[$i]['price'] += $v->price;

                                }
                            }
                            foreach ($datasMember as $k=>$v){
                                $temp_date_obj = new \DateTime($v->created_at);
                                if($temp_date_obj->format('H')==$start_d->format('H')){
                                    $data1[$i]['count']++;
                                }
                            }
                            $data[$i]['price'] = round($data[$i]['price'],2);

                        }
                    }
                }
            }
        }

        return ['title'=>$title,'data'=>$data,'dataMember'=>$data1];
    }
    private function scenceReport($model,$data){
        $title = '景点浏览统计';
        $where = [];
        if(isset($this->options['where'])){
            $where = $this->options['where'];
        }
        $this->countReport($model,$title,$data,'count',$where,false);
        return ['title'=>$title,'data'=>$data];
    }
    private function sumReport($model,&$title,&$data,$field='price',$where=[],$trashed=true){
        if(isset($this->request->searchTime)&&$this->request->searchTime!=''){
            $timeArray=explode('~',$this->request->searchTime);
            $start_time=trim($timeArray[0]);
            $end_time=trim($timeArray[1]);
            $start_obj = new \DateTime($start_time);
            $end_obj = new \DateTime($end_time);
            $diff = date_diff($start_obj,$end_obj);

            if(Auth::user()->can('comboAllOrder')&&$trashed){
                $datas = $model->select('combo_orders.created_at','combo_orders.'.$field)->join('pay_orders','pay_orders.out_trade_no','=','combo_orders.OutTradeNo')->where('pay_orders.is_pay',1)->whereBetween('combo_orders.created_at',[$start_time,$end_time])->withTrashed()->where($where)->get();
            }else{
                $datas = $model->select('combo_orders.created_at','combo_orders.'.$field)->join('pay_orders','pay_orders.out_trade_no','=','combo_orders.OutTradeNo')->where('pay_orders.is_pay',1)->whereBetween('combo_orders.created_at',[$start_time,$end_time])->where($where)->get();

            }
            //dd($datas);
            //判断相差日子
            if($this->getRange($diff)){
                //大于1年则按年统计
                $title = '年'.$title;
                if($this->isCeil($diff))$diff->y = $diff->y+1;
                for($i = 0;$i<=$diff->y;$i++){
                    $incrementTime = new \DateInterval("P{$i}Y");
                    $date = new \DateTime($start_time);
                    $start_d = date_add($date,$incrementTime);
                    $data[$i] = ['date'=>date_format($start_d,'Y'),$field=>0];
                    foreach ($datas as $k=>$v){
                        $temp_date_obj = new \DateTime($v->created_at);
                        if($temp_date_obj->format('Y')==$start_d->format('Y')){
                            $data[$i][$field] += $v->{$field};

                        }

                    }
                    $data[$i][$field] = round($data[$i][$field],2);

                }

            }else{
                //小于或等于一年
                if($this->getRange($diff,'m')){
                    $title = '月'.$title;
                    //大于一个月则按月统计
                    if($diff->y==1&&$diff->m==0)$diff->m=12;
                    if($this->isCeil($diff,'m'))$diff->m = $diff->m+1;

                    for($i = 0;$i<=$diff->m;$i++){
                        $incrementTime = new \DateInterval("P{$i}M");
                        $date = new \DateTime($start_time);
                        $start_d = date_add($date,$incrementTime);
                        $data[$i] = ['date'=>date_format($start_d,'Y/m'),$field=>0];
                        foreach ($datas as $k=>$v){
                            $temp_date_obj = new \DateTime($v->created_at);
                            if($temp_date_obj->format('Y/m')==$start_d->format('Y/m')){
                                $data[$i][$field] += $v->{$field};

                            }
                        }
                        $data[$i][$field] = round($data[$i][$field],2);

                    }
                }else{
                    //小于或等于一个月
                    if($this->getRange($diff,'d')){
                        $title = '日'.$title;
                        //小于一个月大于一日则天统计
                        if($diff->m==1&&$diff->d==0){
                            $days = date('t',strtotime($start_time));
                            $diff->d = $days;
                        }
                        if($this->isCeil($diff,'d')){
                            $diff->d = $diff->d+1;
                        }

                        for($i = 0;$i<=$diff->d;$i++){
                            $incrementTime = new \DateInterval("P{$i}D");
                            $date = new \DateTime($start_time);
                            $start_d = date_add($date,$incrementTime);
                            $data[$i] = ['date'=>date_format($start_d,'m/d'),$field=>0];
                            foreach ($datas as $k=>$v){
                                $temp_date_obj = new \DateTime($v->created_at);
                                if($temp_date_obj->format('m/d')==$start_d->format('m/d')){
                                    $data[$i][$field] += $v->{$field};

                                }
                            }
                            $data[$i][$field] = round($data[$i][$field],2);

                        }
                    }else{
                        $title = '时'.$title;
                        //小时统计
                        //小于一个月大于一日则天统计
                        if($diff->d==1&&$diff->h==0)$diff->h=24;
                        if($this->isCeil($diff))$diff->h = $diff->h+1;

                        for($i = 0;$i<=$diff->h;$i++){
                            $incrementTime = new \DateInterval("PT{$i}H");
                            $date = new \DateTime($start_time);
                            $start_d = date_add($date,$incrementTime);
                            $data[$i] = ['date'=>date_format($start_d,'H:00'),$field=>0];
                            foreach ($datas as $k=>$v){
                                $temp_date_obj = new \DateTime($v->created_at);
                                if($temp_date_obj->format('H')==$start_d->format('H')){
                                    $data[$i][$field] += $v->{$field};

                                }
                            }
                            $data[$i][$field] = round($data[$i][$field],2);

                        }
                    }
                }
            }
        }

    }
    private function countReport($model,&$title,&$data,$field='count',$where=[],$trashed=true){
        if(isset($this->request->searchTime)&&$this->request->searchTime!=''){
            $timeArray=explode('~',$this->request->searchTime);
            $start_time=trim($timeArray[0]);
            $end_time=trim($timeArray[1]);
            $start_obj = new \DateTime($start_time);
            $end_obj = new \DateTime($end_time);
            $diff = date_diff($start_obj,$end_obj);
            if(Auth::user()->can('comboAllOrder')&&$trashed){
                $datas = $model->select('created_at')->whereBetween('created_at',[$start_time,$end_time])->withTrashed()->where($where)->get();
            }else{
                $datas = $model->select('created_at')->whereBetween('created_at',[$start_time,$end_time])->where($where)->get();

            }
            //判断相差日子
            if($this->getRange($diff)){
                //大于1年则按年统计
                $title = '年'.$title;
                if($this->isCeil($diff))$diff->y = $diff->y+1;
                for($i = 0;$i<=$diff->y;$i++){
                    $incrementTime = new \DateInterval("P{$i}Y");
                    $date = new \DateTime($start_time);
                    $start_d = date_add($date,$incrementTime);
                    $data[$i] = ['date'=>date_format($start_d,'Y'),$field=>0];
                    foreach ($datas as $k=>$v){
                        $temp_date_obj = new \DateTime($v->created_at);
                        if($temp_date_obj->format('Y')==$start_d->format('Y')){
                            $data[$i][$field]++;

                        }
                    }
                }

            }else{
                //小于或等于一年
                if($this->getRange($diff,'m')){
                    $title = '月'.$title;
                    //大于一个月则按月统计
                    if($diff->y==1&&$diff->m==0)$diff->m=12;
                    if($this->isCeil($diff,'m'))$diff->m = $diff->m+1;

                    for($i = 0;$i<=$diff->m;$i++){
                        $incrementTime = new \DateInterval("P{$i}M");
                        $date = new \DateTime($start_time);
                        $start_d = date_add($date,$incrementTime);
                        $data[$i] = ['date'=>date_format($start_d,'Y/m'),$field=>0];
                        foreach ($datas as $k=>$v){
                            $temp_date_obj = new \DateTime($v->created_at);
                            if($temp_date_obj->format('Y/m')==$start_d->format('Y/m')){
                                $data[$i][$field]++;

                            }
                        }

                    }
                }else{
                    //小于或等于一个月
                    if($this->getRange($diff,'d')){
                        $title = '日'.$title;
                        //小于一个月大于一日则天统计
                        if($diff->m==1&&$diff->d==0){
                            $days = date('t',strtotime($start_time));
                            $diff->d = $days;
                        }
                        if($this->isCeil($diff,'d')){
                            $diff->d = $diff->d+1;
                        }

                        for($i = 0;$i<=$diff->d;$i++){
                            $incrementTime = new \DateInterval("P{$i}D");
                            $date = new \DateTime($start_time);
                            $start_d = date_add($date,$incrementTime);
                            $data[$i] = ['date'=>date_format($start_d,'m/d'),$field=>0];
                            foreach ($datas as $k=>$v){
                                $temp_date_obj = new \DateTime($v->created_at);
                                if($temp_date_obj->format('m/d')==$start_d->format('m/d')){
                                    $data[$i][$field]++;

                                }
                            }

                        }
                    }else{
                        $title = '时'.$title;
                        //小时统计
                        //小于一个月大于一日则天统计
                        if($diff->d==1&&$diff->h==0)$diff->h=24;
                        if($this->isCeil($diff))$diff->h = $diff->h+1;

                        for($i = 0;$i<=$diff->h;$i++){
                            $incrementTime = new \DateInterval("PT{$i}H");
                            $date = new \DateTime($start_time);
                            $start_d = date_add($date,$incrementTime);
                            $data[$i] = ['date'=>date_format($start_d,'H:00'),$field=>0];
                            foreach ($datas as $k=>$v){
                                $temp_date_obj = new \DateTime($v->created_at);
                                if($temp_date_obj->format('H')==$start_d->format('H')){
                                    $data[$i][$field]++;

                                }
                            }

                        }
                    }
                }
            }
        }

    }

    private function getRange($diff,$level='y'){
        if($level=='y'){
            return $diff->y>1||($diff->y==1&&($diff->m||$diff->d||$diff->h||$diff->i||$diff->s));
        }elseif($level=='m'){
            return $diff->m>1||($diff->m==1&&($diff->d||$diff->h||$diff->i||$diff->s))||$diff->y==1;
        }elseif($level=='d'){
            return $diff->d>1||($diff->d==1&&($diff->h||$diff->i||$diff->s))||$diff->m==1;
        }elseif($level=='h'){
            return $diff->h>1||($diff->h==1&&($diff->i||$diff->s))||$diff->d==1;
        }elseif($level=='i'){
            return $diff->i>1||($diff->i==1&&($diff->s))||$diff->h==1;
        }
    }
    private function isCeil($diff,$level='y'){
        if($level=='y'){
            return $diff->m||$diff->d||$diff->h||$diff->i||$diff->s;
        }elseif($level=='m'){
            return $diff->d||$diff->h||$diff->i||$diff->s;
        }elseif($level=='d'){
            return $diff->h||$diff->i||$diff->s;
        }elseif($level=='h'){
            return $diff->i||$diff->s;
        }elseif($level=='i'){
            return $diff->s;
        }
    }
}